import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { merge } from 'lodash'

export type ApiKey =
  | 'add_column'
  | 'aggregate_avg'
  | 'aggregate_count'
  | 'aggregate_max'
  | 'aggregate_min'
  | 'aggregate_sum'
  | 'column_exists'
  | 'create_table'
  | 'delete_entity'
  | 'delete_record'
  | 'drop_column'
  | 'drop_table'
  | 'execute_raw_sql'
  | 'get_column_types'
  | 'get_primary_key'
  | 'get_table_columns'
  | 'get_tables'
  | 'get_uuid'
  | 'insert_record'
  | 'paginate_entity'
  | 'rename_column'
  | 'rename_table'
  | 'save_entity'
  | 'select_one_record'
  | 'select_records'
  | 'table_exists'
  | 'truncate_table'
  | 'update_entity'
  | 'update_record'
  | 'select_join'
  | 'get_tables_used'
  | 'set_tables_used'

export class HttpClient {
  private client: AxiosInstance

  constructor(baseURL: string) {
    this.client = axios.create({
      baseURL,
      method: 'post',  
      headers: {
        'Content-Type': 'application/json'
      }
    })
  }

  public async request<P = any, T = any>(key: ApiKey, data?: P, config?: AxiosRequestConfig): Promise<T> {
    const mergedConfig = merge({}, config) 
    const response: AxiosResponse = await this.client.post<T>(`/${key}`, data, mergedConfig)
    return response.data as T
  }
}
